<template>
  <div class="image-video-upload">
    <div v-if="topTitle" style="color:grey;">{{topTitle}}</div>
    <div v-if="id" class="upload-success" :style="imageStyle">
      <custom-image :image-id="id" class="result-image" :style="imageStyle">
      </custom-image>
      <i v-if="!disabled" class="el-icon-circle-close" @click="handleRemove" />
    </div>
    <el-upload
      v-show="!id"
      ref="uploader"
      class="uploader"
      :action="action"
      :disabled="disabled || uploading"
      :headers="headers"
      :data="data"
      :accept="accept"
      :show-file-list="false"
      :on-success="handlerSuccess"
      :on-error="handlerError"
      :before-upload="beforeUploadHandler"
      :style="imageStyle"
      :on-progress="handleProcess"
    >
      <el-progress v-if="uploading" type="circle" :percentage="percentage" :width="80" />
      <i v-else class="el-icon-plus" />
    </el-upload>
    <div class="el-upload__tip" v-html="tip" />
  </div>
</template>

<script>
import CustomImage from './CustomImage.vue'
import { getToken } from '@/utils/auth'
import { getImageUrl } from '@/utils'

export default {
  components: { CustomImage },
  name: 'UploadImage',
  props: {
    topTitle: {
      type: String,
      default: ''
    },
    value: {
      type: [String, Number],
      default: ''
    },
    tip: {
      type: String,
      default: ''
    },
    // 控制图片样式（长宽等）
    imageStyle: {
      type: String,
      default: 'width: 200px;height: 100px;'
    },
    accept: {
      type: String,
      default: '.jpg,.jpeg,.png,.gif,.bmp,.JPG,.JPEG,.PBG,.GIF,.BMP'
    },
    width: {
      type: Number,
      default: 0
    },
    height: {
      type: Number,
      default: 0
    },
    // 图片尺寸验证类型
    validType: {
      type: Number,
      default: 0 // 0：比列验证，1：实际大小验证
    },
    // 图片尺寸验证
    valid: {
      type: Number,
      default: 0 // 0: 不验证，不提示  1：验证提示，不停止上传 2: 验证提示，停止上传
    },
    // 图片大小验证，单位M
    imageSize: {
      type: Number,
      default: 3
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      uploading: false,
      id: this.value || '',
      action: `${process.env.BASE_API}/base/attachment/upload`,
      headers: {
        token: getToken()
      },
      data: {
        prefixMenu: 'image'
      },
      percentage: 0
    }
  },
  watch: {
    value(value) {
      this.id = value
    }
  },
  methods: {
    handleProcess(event, file, fileList) {
      this.percentage = +file.percentage.toFixed(0)
    },
    beforeUploadHandler(file) {
      this.uploading = true
      this.percentage = 0
      const fileSize = file.size / 1024 / 1024
      if (fileSize > this.imageSize) {
        this.uploading = false
        this.$message.error(`图片文件大小不能超过 ${this.imageSize}MB!`)
        return false
      } else if (this.valid == 0 || this.width == 0 || this.height == 0) {
        return true
      }

      return new Promise((resolve, reject) => {
        this.filetoDataURL(file, url => {
          this.dataURLtoImage(url, img => {
            const { width, height } = this

            let validTemp = true
            let str = ''
            if (this.validType == 0) {
              validTemp =
                  (width / height).toFixed(2) ==
                  (img.width / img.height).toFixed(2)
              str = '比例'
            } else {
              validTemp = width == img.width && height == img.height
              str = '宽高'
            }
            if (!validTemp) {
              this.$message.error(`图片${str}不符合建议要求！`)
              if (this.valid == 2) {
                this.uploading = false
                return reject()
              }
            }
            resolve()
          })
        })
      })
    },
    handlerSuccess(res) {
      if (res.success) {
        const item = res.data
        this.uploading = false
        this.setValue(item)
      }
    },
    handlerError() {
      this.uploading = false
    },
    setValue(item) {
      if (item) {
        this.item = item.id
        this.$emit('input', getImageUrl(item.id))
        this.$emit('change', item)
      } else {
        this.$emit('input', '')
        this.$emit('change', '')
      }
    },
    handleRemove() {
      this.setValue('')
    }
  }
}
</script>

<style lang="scss" scoped>
.image-video-upload {
  // display: flex;
  // flex-direction: column;

  .uploader,
  .result-image {
    display: flex;
    font-size: 28px;
    color: #8c939d;
    text-align: center;
    background-color: #fbfdff;
    border: 1px dashed #c0ccda;
    border-radius: 6px;
    cursor: pointer;
  }

  .result-image {
    border: 1px solid #c0ccda;
  }

  .uploader{
    &:hover {
      border-color: #409eff;
      color: #409eff;
    }
  }

  /deep/ {
    .el-upload{
      width: 100%;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;

      &:focus{
        border-color: #fbfdff;
        color: #8c939d;
      }

      &:hover{
        border-color: #409eff;
        color: #409eff;
      }
    }
  }

  .el-upload__tip {
    flex: 1;
    line-height: 21px;
    display: flex;
    align-items: center;
    margin-left: 20px;
    margin-top: 0;
  }

  .upload-success {
    position: relative;
    border-radius: 6px;
    overflow: hidden;

    &:hover {
      .icon-success {
        display: none;
      }
    }

    .el-icon-circle-close{
      position: absolute;
      top: 5px;
      right: 5px;
      font-size: 20px;
      color: #F56C6C;
    }
  }

  .icon-success {
    position: absolute;
    right: -15px;
    top: -6px;
    width: 40px;
    height: 24px;
    // line-height: 24px;
    text-align: center;
    background: #13ce66;
    -webkit-transform: rotate(45deg);
    transform: rotate(45deg);
    -webkit-box-shadow: 0 0 1pc 1px rgba(0, 0, 0, 0.2);
    box-shadow: 0 0 1pc 1px rgba(0, 0, 0, 0.2);

    .el-icon-check {
      color: #ffffff;
      -webkit-transform: rotate(-45deg);
      transform: rotate(-45deg);
    }
  }
  .el-icon-delete {
    font-size: 20px;
    color: #fff;
    cursor: pointer;
  }
}
</style>
